--
-- TeamModel
-- 队伍相关信息
-- 包含：	1、队伍基础信息、成员、队伍招募设置、投票等队伍数据本身的信息
--			2、队伍周边信息：例如队伍环任务、所处地图？等等
-- 			3、可能还有关于某一个地下城所有的队伍列表

local TeamVo = import(".TeamVo")
local TeamRecruitInfoVo = import(".TeamRecruitInfoVo")
local TeamMatchCrossInfo = import(".TeamMatchCrossInfo")

local string_split = string.split

local fileName = string.getModeName(...)
local ClassRef = class(fileName, app.mvc.ModelBase)

function ClassRef:ctor(data)
	self.super.ctor(self, data)
end

function ClassRef:init()
	self._team = nil -- 整个队伍的信息
	self._applyList = {} -- 申请信息列表

	self._crossMatchDatas = {} -- 跨服匹配信息

	-- 总是跟随队伍
--	self._alwaysWithTeam = false

	self:initTeamTarget()
end

-- 是否军团
function ClassRef:isCrossTeam()
	if self._team then
		return self._team:isCrossTeam()
	end
	return false
end

-- 是否军团
function ClassRef:isLegion()
	return self._team and self._team:isLegion() or false
end

-- uid是否跟随军团长
function ClassRef:isWithLegion(uid)
	return self:isLegion() and self:isWithTeam(uid)
end

-- uid是否跟随队长
function ClassRef:isWithTeam(uid)
	uid = uid or UD.player.uid
	if self._team then
		return self._team:isWithTeam(uid)
	end
	return false
end

-- uid是否在队伍中
function ClassRef:isInTeam(uid)
	uid = uid or UD.player.uid
	if self._team then
		return self._team:isInTeam(uid)
	end
	return false
end

-- 是否在跨服副本匹配中
function ClassRef:isInCrossDungeonMatch()
	return #self._crossMatchDatas > 0 
end

function ClassRef:getCrossMatchDatas()
	return self._crossMatchDatas
end

function ClassRef:getTeamMatchCrossInfo()
	return self._teamMatchCrossInfo
end

-- 没有队伍 or 有队伍只有自己一个人(无队友且无机器人)
function ClassRef:isSingle()
	if self._team then
		return (self._team:getRobotNum() + self._team:getMemberNum()) == 1
	end
	return true
end

-- 是否"我"的队伍（即："我"是不是队长）
function ClassRef:isMyTeam()
	if self._team then
		return self._team:isMyTeam()
	end
	return false
end

-- 是否可以进行pvp匹配
function ClassRef:pvpMatchingEnabled()
	if self:hasTeam() then
		return self:isMyTeam()
	else
		-- 不是没有队伍就可以pvp匹配
		return true
	end
end

-- uid是否队长
function ClassRef:isLeader(uid)
	uid = uid or UD.player.uid
	if self._team then
		return self._team:isLeader(uid)
	end
	return false
end

-- uid是否暂离状态
function ClassRef:isAwayFromTeam(uid)
	uid = uid or UD.player.uid
	if self._team then
		return self._team:isAwayFromTeam(uid)
	end
	return false
end

-- 队伍中是否存在与"我"同工会的成员
function ClassRef:isHaveSameGuild()
	if self._team then
		return self._team:isHaveSameGuild()
	end
	return false
end

-- 队伍是否满员
function ClassRef:isTeamFull()
	if self._team then
		return self._team:isTeamFull()
	end
	return false, nil
end


-- 队伍是否满员
function ClassRef:getMaxPartnerNum()
	if self._team then
		return self._team:getMaxPartnerNum()
	end
	return 4, false
end

-- 队伍是否正常状态
function ClassRef:isTeamNormal()
	if self._team then
		return self._team:isTeamNormal()
	end
	return false
end
-- 队伍是否繁忙状态
function ClassRef:isTeamBusy()
	if self._team then
		return self._team:isTeamBusy()
	end
	return false
end
-- 队伍是否战斗状态
function ClassRef:isTeamBattle()
	if self._team then
		return self._team:isTeamBattle()
	end
	return false
end

-- 返回队伍id
function ClassRef:getTeamId()
	if self._team then
		return self._team:getTeamId()
	end
	return nil
end

-- 返回队伍中 uid 成员
function ClassRef:getMember(uid)
	uid = uid or UD.player.uid
	if self._team then
		return self._team:getMember(uid)
	end
	return nil
end

-- 返回队伍中所有队员
function ClassRef:getMembers()
	if self._team then
		return self._team:getMembers()
	end
	return {}
end

-- 返回队伍中所有机器人
function ClassRef:getRobots()
	if self._team then
		return self._team:getRobots()
	end
	return {}
end

-- 返回队长uid
function ClassRef:getLeaderUid()
	if self._team then
		return self._team:getLeaderUid()
	end
	return nil
end

function ClassRef:getLeaderPartnerInfo()
	if self._team then
		return self._team:getLeaderPartnerInfo()
	end
	return {}
end

-- 返回队伍战斗力
function ClassRef:getTeamTotalCapacity(withPartner)
	if self._team then
		return self._team:getTeamTotalCapacity(withPartner)
	end
	return 0
end

-- 返回队伍设置信息
function ClassRef:getTeamSetting()
	if self._team then
		return self._team:getTeamSetting()
	end
	return {}
end

-- 返回队伍设置信息的拷贝
function ClassRef:getTeamSettingClone()
	if self._team then
		return self._team:getTeamSettingClone()
	end
	return {}
end

-- 比较 tempRecruitInfo 与 self._team 中的 RecruitInfo 是否完全相等
function ClassRef:isTwoRecruitInfoEqual( tempRecruitInfo )
	if self._team then
		return self._team:isTwoRecruitInfoEqual( tempRecruitInfo )
	end
	return true -- 默认是相等的
end

-- 返回队伍目标id
function ClassRef:getTeamTargetId()
	if self._team then
		return self._team:getTeamTargetId()
	end
	return 0
end

-- 返回队伍目标VO
function ClassRef:getTeamTargetVo()
	if self._team then
		return self._team:getTeamTargetVo()
	end
	return nil
end

-- 返回除"我"之外的队员
function ClassRef:getOtherMembers()
	if self._team then
		return self._team:getOtherMembers()
	end
	return {}
end

-- 返回成员个数
function ClassRef:getMemberNum()
	if self._team then
		return self._team:getMemberNum()
	end
	return 1
end

-- 队伍成员最小等级
function ClassRef:getMemberMinLv()
	if self._team then
		return self._team:getMemberMinLv()
	end
	return 1
end

-- 返回队伍性质
function ClassRef:getTeamGrade()
	if self._team then
		return self._team:getTeamGrade()
	end
	return nil
end

-- 返回跟随队伍的成员个数
-- withRobot 是否计算机器人
function ClassRef:getWithTeamNum(withRobot)
	if self._team then
		return self._team:getWithTeamNum(withRobot)
	end
	return 0
end

-- 返回队伍平均等级
function ClassRef:getAverageTeamLevel()
	if self._team then
		return self._team:getAverageTeamLevel()
	end
	return 0
end

-- 根据队伍性质返回队伍成员个数上限
function ClassRef:getMaxNumOfMembersByTeamGarde( garde )
	garde = garde or self:getTeamGrade()
	local maxNum = TeamVo:getMaxNumOfMembersByTeamGarde( garde ) or 0
	return maxNum
end

-- 返回队伍招募设置中的"自动申请"状态
function ClassRef:isAutoApprove()
	if self._team then
		return self._team:isAutoApprove()
	end
	return false
end

------------------------------------------>>>>>> 新队伍相关辅助函数 <<<<<<------------------------------------------
-- 返回申请列表中记录的申请者
function ClassRef:getApplicantList()
	return self._applyList
end

function ClassRef:hasTeam()
	return self._team ~= nil
end

function ClassRef:setTeam(team, isCrossTeam)
	-- 清理自动申请目标
	for i,id in ipairs(self._curAutoApplyTargetIds) do
		local teamTarget = self._teamTargetDict[id]
		teamTarget:setAutoApply(false)
	end
	self._curAutoApplyTargetIds = {}

	if team then
		local preTeamTargetId = 0
		if self._team then
			preTeamTargetId = self._team:getTeamTargetId()
			self._team:read(team)
		else
			self._team = TeamVo.new(team)
		end
		self._team:setIsCrossTeam(isCrossTeam)

		local teamTargetId = self._team:getTeamTargetId()
		if preTeamTargetId > 0 and preTeamTargetId ~= teamTargetId then
			local preTeamTarget = self:getTeamTargetById(preTeamTargetId)
			if preTeamTarget then
				preTeamTarget:setAutoRecruit(false)
			end
		end
		-- print("TeamModel.setTeam preTeamTargetId teamTargetId", preTeamTargetId, teamTargetId)
		self._team:setTeamTargetVo(self:getTeamTargetById(teamTargetId), true)
		self:updateTeam()
	else
		self:clearTeam()
	end
end

function ClassRef:getTeam()
	return self._team
end

function ClassRef:updateTeam()
	app:dispatchCustomEvent("EVENT_TEAM_UPDATE")
	EM:notify("onTeamUpdate", self._team)
end

function ClassRef:clearTeam()
	if self._team then
		-- 清理 TeamTarget 自动招募
		local teamTargetId = self._team:getTeamTargetId()
		local teamTarget = self._teamTargetDict[teamTargetId]
		-- print("clearTeam teamTargetId", teamTargetId, teamTarget)
		if teamTarget then
			teamTarget:setAutoRecruit(false)
			app:sendMsg("TeamMatchController", "updateAutoRecruit", teamTarget)
			app:sendMsg("PvpEliteController", "updateAutoRecruit", teamTarget)
			app:sendMsg("PvpChallengeController", "updateAutoRecruit", teamTarget)
		end

		self._team:clear()
	end
	self._team = nil
	self._applyList = {}

	app:sendMsg("NewTeamMemberController", "closeView")
	app:sendMsg("NewTeamApplyController", "closeView")
	app:sendMsg("NewTeamReadyAndSettingController", "closeView")
	app:sendMsg("NewTeamSettingController", "closeView")
	app:sendMsg("TeamMatchController", "removeInviteFollowDialog")

	-- self:clearTeamCircle(true)
	self:updateTeam()
end

--function ClassRef:setAlwaysWithTeam(isWith)
--    self._alwaysWithTeam = isWith
--end

--function ClassRef:getAlwaysWithTeam()
--    return self._alwaysWithTeam
--end

-- 更新队伍跨服匹配状态
function ClassRef:updateTeamCrossMatch(targetId, b)
	if self._team then
		self._team:setIsInCrossMatch(self:isInCrossMatch())
	end

	if targetId then
		local teamTarget = self:getTeamTargetById(targetId)
		if teamTarget then
			teamTarget:setIsInCrossMatch(b)
		end
	end
end

-- 跨服匹配中
function ClassRef:isInCrossMatch()
	local isInChallengeMatch = app:sendMsg("PvpModel", "isInChallengeMatch")
	local isInEliteMatch = UD.csEliteMatch:isInEliteMatch()
	local isInDungeonMatch = self:isInCrossDungeonMatch()
	return isInChallengeMatch or isInEliteMatch or isInDungeonMatch
end

-- 检测是否可以跨服匹配（废弃，三个匹配可以共存）
-- function ClassRef:checkCrossMatchEnable(crossMatchType)
-- 	local isInChallengeMatch = app:sendMsg("PvpModel", "isInChallengeMatch")
-- 	local isInEliteMatch = UD.csEliteMatch:isInEliteMatch()
-- 	local isInDungeonMatch = self:isInCrossDungeonMatch()

-- 	local enable = true
-- 	local tips, preTargetName, curTargetName
-- 	if crossMatchType == Enums.CrossMatchType.Dungeon then
-- 		-- 地下城
-- 		enable = not (isInEliteMatch or isInChallengeMatch)
-- 		curTargetName = L("CrossServerTips6")
-- 		if isInEliteMatch then
-- 			preTargetName = L("CrossServerTips7")
-- 		elseif isInChallengeMatch then
-- 			preTargetName = L("CrossServerTips8")
-- 		end
-- 	elseif crossMatchType == Enums.CrossMatchType.Challenge then
-- 		-- 挑战赛
-- 		enable = not (isInEliteMatch or isInDungeonMatch)
-- 		curTargetName = L("CrossServerTips8")
-- 		if isInEliteMatch then
-- 			preTargetName = L("CrossServerTips7")
-- 		elseif isInDungeonMatch then
-- 			preTargetName = L("CrossServerTips6")
-- 		end
-- 	elseif crossMatchType == Enums.CrossMatchType.Elite then
-- 		-- 精英赛
-- 		enable = not (isInDungeonMatch or isInChallengeMatch)
-- 		curTargetName = L("CrossServerTips7")
-- 		if isInDungeonMatch then
-- 			preTargetName = L("CrossServerTips6")
-- 		elseif isInChallengeMatch then
-- 			preTargetName = L("CrossServerTips8")
-- 		end
-- 	end
-- 	if not enable then
-- 		tips = string.format(L("CrossServerTips9"), curTargetName, preTargetName)
-- 	end
-- 	return enable, tips
-- end

--------------------------------------------------------------------------------------->>>>>> 新队伍相关协议
function ClassRef:reqCreateTeam( recruitInfo)
	recruitInfo = recruitInfo or TeamRecruitInfoVo:getCreateRecruitInfo()

	-- 在个人跨服副本匹配中，创建队伍关闭自动招募和自动批准
	if self:isInCrossMatch() then
		recruitInfo.autoApprove = false
		recruitInfo.autoRecruit = false
	end

	app.session:request("pb_team.C2S_CreateTeam", { recruitInfo = recruitInfo }, function(ret)
		-- dump( ret, " ------------>>>>> reqCreateTeam ret ", 10 )
		if ret.OK then
			--display.pushToast( L("创建队伍成功!") )
			EM:notify("onCreateTeam")
		else
			--display.pushToast( L("创建队伍失败!") )
		end
	end)
end

-- 邀请进队
function ClassRef:reqInviteToTeam( targetUid, targetLv) -- 目标玩家uid
	-- 副本中邀请人需要考虑等级是否满足
	if targetLv and DungeonManager:isInDungeon() then
		local openLv = DungeonManager:getDungeonOpenLv()
		if targetLv < openLv then
			display.pushToast(L("team_text8"))
			return
		end
	end

	local function inviteToTteam()
		-- print( " -------->>>>>>>>> reqInviteToTeam: ", targetUid)
		app.session:request("pb_team.C2S_InviteToTeam", { playerID = targetUid }, function(ret)
			-- dump( ret, " ------------>>>>> reqInviteToTeam ret ", 10 )
			if ret.OK then
				display.pushToast( L("team_text9") )
			end
		end)
	end

	-- 在跨服匹配中，邀请队友需要弹强提示
	if self:isInCrossMatch() then
		local dlg = display.newConfirmDialog(L("CrossServerTips3"),
		        function() -- 确定
		        	inviteToTteam()
		        end)
		UIHandler:addPopDialog( dlg )
	else
		inviteToTteam()
	end

end

-- 主动申请进队
-- targetUid    申请目标的角色id（必须）
-- targetId     玩法目标id，检测队伍目标和该目标是否一致，如果有值而该队伍已经修改目标则不会入队
-- team         申请的队伍结构
function ClassRef:reqApplyJoinTeam(targetUid, targetId, team)
	app.session:request("pb_team.C2S_ApplyJoinTeam", {playerID=targetUid, targetId=targetId}, function(ret)
		-- dump(ret, "C2S_ApplyJoinTeam")
	    if ret.OK then
	        display.pushToast(L("TeamRepeatAlready"))
	        -- print("C2S_ApplyJoinTeam", targetId, team and team:getTeamId())
	        if team then
	            -- 如果传入了队伍，修改队伍的已申请状态
	            team:addApplyUid(UD:getUid())
				app:sendMsg("TeamMatchController", "refreshTeamListApply", team)
				app:sendMsg("PvpEliteController", "refreshTeamListApply", team)
				app:sendMsg("PvpChallengeController", "refreshTeamListApply", team)
	        end
	    end
	end, nil,
	function(errMsg)
	    -- 所申请的目标有错，从新拉取一次队伍列表
	    if targetId and team then
	        self:C2S_GetTeamList(targetId)
	    end
	    return false
	end)
end

-- 回复邀请组队
function ClassRef:reqApplyJoinTeamByInvited( replyState, inviteInfo, rejedctReason )
	-- dump( inviteInfo, " ------------>>>>> reqApplyJoinTeamByInvited " .. tostring( replyState ) .. " ; " .. tostring( rejedctReason ), 10 )
	app.session:request("pb_team.C2S_ReplyInviteToTeam", { replyState = replyState, inviteInfo = inviteInfo, rejedctReason = rejedctReason },
		function(ret)
		-- dump( ret, " ------------>>>>> reqApplyJoinTeamByInvited ret ", 10 )
		if ret.OK then
			if replyState then
				app:sendMsg("NewTeamMemberController", "openView")
			end
		end
	end)
end

-- 队长回应申请者的申请
-- 此方法一定只会被队伍的队长调用
function ClassRef:reqReplyApplication( playerIdTemp, agreeTemp )
	local function removeOpTarget()
		for i,apply in ipairs(self._applyList) do
			if apply.uid == playerIdTemp then
				table.remove( self._applyList, i )
				break
			end
		end
		app:sendMsg("NewTeamApplyController", "updateApplyList")
		app:sendMsg("TeamMatchController", "refreshApplyNew")
		app:sendMsg("NewTeamMemberController", "refreshNewApplyerFlag")
		app:sendMsg("PvpChampionController", "_refreshNewApplyerFlag")
		app:sendMsg("PvpEliteController", "refreshNewApplyerFlag")
		app:sendMsg("PvpChallengeController", "refreshApplyNew")
        if not self:isNewApplyerFlag() then
            -- 通知移除桌面tips
            UIHandler:getDesktopController():removeFourthTipsByType( Constant.FUNC_TYPE_TEAM_APPLY )
        end
	end

	-- print( " -------->>>>>>>>> reqReplyApplication: ", playerIdTemp, agreeTemp )
	app.session:request("pb_team.C2S_ReplyApplication", { playerID = playerIdTemp, replyState = agreeTemp }, 
		function(ret)
			-- dump( ret, " ------------>>>>> reqReplyApplication ret ", 10 )
			if ret.OK then -- 操作成功
				removeOpTarget()
			end
		end, nil,
		function(errMsg)
			if "ErrTargetIsInTeam" == errMsg.content or "ErrThisGuyIsBusy" == errMsg.content then  -- 操作目标状态发生变化
				removeOpTarget()
			end
		end)
end

-- 请求转移队伍队长
function ClassRef:reqPromoteTeamLeader( targetUid )
	-- print( " -------->>>>>>>>> reqPromoteTeamLeader: ".. targetUid)
	app.session:request("pb_team.C2S_ChangeTeamLeader", { playerID = targetUid }, function(ret)
		-- dump( ret, " ------------>>>>> reqPromoteTeamLeader ret ", 10 )
		-- if ret.OK then
		-- 	display.pushToast( L( "委任队长成功!" ) )
		-- end
	end)
end

-- 跟随队长状态上传
function ClassRef:reqFollowLeader( followTemp )
	-- print( " -------->>>>>>>>> reqFollowLeader: ", followTemp )
	app.session:request("pb_team.C2S_FollowLeader", { follow = followTemp },
		function(ret)
			-- dump( ret, " ------------>>>>> reqFollowLeader ret ", 10 )
			if ret.OK then
				--display.pushToast( L( "跟随状态切换成功!" ) )
			end
		end, nil,
		function(errMsg)
		end)
end

-- 退出队伍
function ClassRef:reqQuitTeam()
	-- print( " -------->>>>>>>>> reqQuitTeam " )
	app.session:request("pb_team.C2S_QuitTeam", {}, function(ret)
		-- dump( ret, " ------------>>>>> reqQuitTeam ret ", 10 )
		if ret.OK then
			--display.pushToast( L("退出队伍成功!") )
			-- self:clearTeam()
		end
	end)
end

-- 踢人
function ClassRef:reqKickTeamMember( targetUid, isRobot)
	-- print( " -------->>>>>>>>> reqKickTeamMember: ", targetUid, isRobot)
	isRobot = isRobot or false
	app.session:request("pb_team.C2S_KickTeamMember", { playerID = targetUid, isRobot=isRobot }, function(ret)
		-- dump( ret, " ------------>>>>> reqKickTeamMember ret ")
		if ret.OK then
			--display.pushToast( L("移出队伍成功!") )
		end
	end)
end

-- 更换队长
function ClassRef:reqImpeachLeader()
    app.session:request("pb_team.C2S_ChangeTeamLeaderByMember", {}, function(ret)
        if ret.ok then

        end
    end)
end

function ClassRef:reqImpeachLeaderResponses(params)
    app.session:request("pb_team.C2S_ReplyChangeTeamLeader", params, function(ret)
        if ret.ok then
--           display.pushToast(L("队长变更成功"))
        end
    end)
end

-- 改变队伍性质 （队伍/战团）
function ClassRef:reqUpdateTeamGrade( newGradeTemp )
	local newTypeTemp = protobuf.enum_name("pb_team.TeamInfo_Type", newGradeTemp)
	-- print( " -------->>>>>>>>> reqUpdateTeamGrade: ", newGradeTemp, newTypeTemp )

	app.session:request("pb_team.C2S_UpdateTeamGrade", { newType = newTypeTemp }, function(ret)
		-- dump( ret, " ------------>>>>> reqUpdateTeamGrade ret ", 10 )
		if ret.OK then
			--display.pushToast( L("修改成功!") )
		end
	end)
end

-- 邀请队员跟随 //uid 为 -1 代表让全队跟随，不为-1的话代表特指某人跟随
function ClassRef:reqInviteFollow(uid)
	uid = uid or -1
	app.session:request("pb_team.C2S_TeamFollowLeader", {Uid=uid}, function(ret)
		-- dump(ret, "C2S_TeamFollowLeader")
	end)
end

-- 队员回复队长跟随 //0代表不同意跟随，1代表同意跟随
function ClassRef:reqReplyFollow(follow)
	-- print("reqReplyFollow", follow)
	app.session:request("pb_team.C2S_ReplyTeamFollowLeader", {Follow=follow}, function(ret)
		-- dump(ret, "C2S_ReplyTeamFollowLeader")
	end)
end

-- 收到队长跟随邀请
function ClassRef:S2C_InviteTeamFollowLeader(msg)
	-- dump(msg, "S2C_InviteTeamFollowLeader")
	if self:_isCrossDungeon() then
		-- 跨服副本，直接拒绝
		self:reqReplyFollow(0)
	elseif BattleManager:isInBattle() then
		self:reqReplyFollow(2)
	elseif StoryManager:isEnterStoryMode() then
		self:reqReplyFollow(3)
	else
		app:sendMsg("TeamMatchController", "openInviteFollowDialog", msg)
	end
end

-- 收到队员跟随邀请回复
function ClassRef:S2C_ReplyTeamFollowLeaderNotice(msg)
	-- dump(msg, "S2C_ReplyTeamFollowLeaderNotice")
	if self._team then
		local member = self._team:getMember(msg.Uid)
		if cc.isAlive(member) then
			local name = member:getName()
			local tipStr = L("TeamClumpTips2")
			if msg.Follow == 0 then
				tipStr = L("TeamClumpTips3")
			elseif msg.Follow == 2 then
				tipStr = L("TeamClumpTips4")
			elseif msg.Follow == 3 then
				tipStr = L("TeamClumpTips5")
			end
			display.pushToast(string.format(tipStr, name))
		end
	end
end

-- 开始投票
-- 只有队伍的队长才会调用此方法
function ClassRef:reqStartVote( targetId, isMatch )
	-- 本地清理队员ready
	self._team:clearAllReady()
	
	-- print( " ------------------->>>>> reqStartVote ", targetId, isMatch )
	local params = { targetID = targetId, isCrossDMatch=isMatch }
	app.session:request("pb_team.C2S_StartTeamReady", params, function(ret)
		-- dump( ret, " ----------->>>>>> reqStartVote ret", 10 )
		if ret.OK then
			display.pushToast( L("team_text11") )
		end
	end)
end

-- 取消投票
-- 只有队伍的队长才会调用此方法
function ClassRef:reqCancelVote()
	-- print( " ------------------->>>>> reqCancelVote " )
	app.session:request("pb_team.C2S_CancelTeamReady", {}, function(ret)
		-- dump( ret, " ----------->>>>>> reqCancelVote ret", 10 )
		app:sendMsg("NewTeamReadyAndSettingController", "closeView")
	end)
end

-- 投票确认结束
-- 只有队伍的队长才会调用此方法
function ClassRef:reqConfirmVote()
	-- print( " ------------------->>>>> reqConfirmVote " )
	app.session:request("pb_team.C2S_ConfirmTeamReady", {}, function(ret)
		-- dump( ret, " ----------->>>>>> reqConfirmVote ret", 10 )
	end)
end

-- 确认投票结束
function ClassRef:onConfirmVote()
	app:sendMsg("NewTeamReadyAndSettingController", "closeView")
	app:sendMsg("TeamMatchController", "closeView")
end

-- 收到取消投票通知
function ClassRef:onCancelVote( ret )
	app:sendMsg("NewTeamReadyAndSettingController", "closeView")
	self:reqGetTeamInfo()
end

-- 回复投票
-- 只有队伍队员会调用此方法
function ClassRef:reqReplyVote( voteResultTemp )
	-- print( " ------------------->>>>> reqReplyVote ", voteResultTemp )
	app.session:request("pb_team.C2S_ReplyTeamReady", { readyResult =  voteResultTemp }, function(ret)
		-- dump( ret, " ----------->>>>>> reqReplyVote ret", 10)
	end)
end

-- 是跨服副本
function ClassRef:_isCrossDungeon()
	return self:isCrossTeam() or DungeonManager:isCrossDungeon()
end

-- 主动拉取申请列表、只能由队长发起
-- fixbug：玩家无限重复申请导致申请列表中全是他 的bug
function ClassRef:reqGetApplicationList()
	-- print( " ------------>>>>>>>> reqGetApplicationList" )
	if self:_isCrossDungeon() then
		-- 跨服副本不需要拉取队伍信息
		print("TeamModel isCrossDungeon can't getApplicationList")
		return
	end

	app.session:request("pb_team.C2S_GetApplicationList", {}, function(ret)
		-- dump( ret, " ----------->>>>>> reqGetApplicationList ret", 10 )

		self._applyList = {}
		if ret.applyMembers then
			for i,v in ipairs( ret.applyMembers ) do
				self._applyList[ #self._applyList + 1 ] = v
			end
			app:sendMsg("NewTeamApplyController", "updateApplyList")
			app:sendMsg("NewTeamMemberController", "refreshNewApplyerFlag")
			app:sendMsg("TeamMatchController", "refreshApplyNew")
			app:sendMsg("PvpChampionController", "_refreshNewApplyerFlag")
			app:sendMsg("PvpController", "_refreshNewApplyerFlag")
			app:sendMsg("PvpEliteController", "refreshNewApplyerFlag")
			app:sendMsg("PvpChallengeController", "refreshApplyNew")
		end
	end)
end


-- 主动拉取队伍信息，
--fixbug:：服务器主动推更新消耗过大
function ClassRef:reqGetTeamInfo()
	-- print( " ------------>>>>>>>> reqGetTeamInfo", DungeonManager:isCrossDungeon())
	if self:_isCrossDungeon() then
		-- 跨服副本不需要拉取队伍信息
		print("TeamModel isCrossDungeon can't getTeamInfo")
		return
	end
	app.session:request("pb_team.C2S_GetTeamInfo", {}, function(ret)
		-- dump( ret, " ----------->>>>>> reqGetTeamInfo ret", 10 )
		self:setTeam( ret.teamInfo, false)
	end)
end

-- 上传玩家状态
function ClassRef:reqPostPlayerState( stateTemp )
	-- print( " -------------->>>>> reqPostPlayerState ", stateTemp )
	if not self:isMyTeam() then return end
	if self:_isCrossDungeon() then
		-- 跨服副本不需要拉取队伍信息
		print("TeamModel isCrossDungeon can't postPlayerState")
		return
	end

	app.session:request("pb_team.C2S_PostActionState", { actionState = stateTemp })
end

---------------------------------------------------------------------------------------<<<<<< 服务器回来消息

-- 收到邀请入队信息
function ClassRef:onTeamNewBeingInvited(ret)
	-- dump( ret, " ----------->>>>>> onTeamNewBeingInvited ", 10 )

	if self:_isCrossDungeon() then
		print("TeamModel isCrossDungeon can't beInvited")
		return
	end

	local params = {
		remindId = Constant.FUNC_TYPE_TEAM_INVITE,
		dataTemp = ret.inviteInfo
	}
	if ret.inviteInfo.teamInfo then
		local targetId = ret.inviteInfo.teamInfo.teamRecruitInfo.targetID
		params.teamTarget = self._teamTargetDict[targetId]
	end
	local desktopController = UIHandler:getDesktopController()
	if desktopController then
		desktopController:insertFourthTips( params )
	end
end

-- 队长收到新的申请信息
function ClassRef:onTeamNewApplication(ret)
	-- dump( ret, " ----------->>>>>> onTeamNewApplication ", 10 )
	if self:_isCrossDungeon() then
		print("TeamModel isCrossDungeon can't handle application")
		return
	end

    --右下角的通知
    local params = {
		remindId = Constant.FUNC_TYPE_TEAM_APPLY
	}
    local desktopController = UIHandler:getDesktopController()
	if desktopController then
		desktopController:insertFourthTips( params )
	end

	display.pushToast(L("team_text12"))
	EM:notify("onTeamNewApplyer")
end

-- 返回新申请者标记
function ClassRef:isNewApplyerFlag()
	return 0 ~= #self._applyList
end

-- 申请者被拒后会收到此条消息
function ClassRef:onApplicationBeRejected(ret)
	-- dump( ret, " ----------->>>>>> onApplicationBeRejected ", 10 )
	display.pushToast( L("team_text13") )
end

-- 发出去的组队邀请反馈
function ClassRef:onInvitationFeedBack(ret)
	-- dump( ret, " ----------->>>>>> onInvitationFeedBack ", 10 )
	if ret.replyState then -- 对方同意邀请？
		display.pushToast( L("team_text14") )
	else
		if ret.rejedctReason then
			if 0 == ret.rejedctReason then
				-- display.pushToast(string.format(L("你发出去的组队邀请被 %s 拒绝了"), ret.rejedcter.name))
				display.pushToast( L("team_text15") )
			elseif 1 == ret.rejedctReason then -- 战斗中
				display.pushToast( L("ErrTargetIsFighting") )
			elseif 2 == ret.rejedctReason then -- 剧情中
				display.pushToast( L("ErrTargetIsInQuest") )
			end
		end
	end
end

-- 收到战备确认投票通知
function ClassRef:onTeamNewVote(ret)
	-- dump( ret, " ----------->>>>>> onTeamNewVote ", 10 )
	if self:_isCrossDungeon() then
		print("TeamModel isCrossDungeon can't vote")
		return
	end

	local targetId = ret.readyTarget
	local isMatch = ret.isCrossDMatch
	if not self:isMyTeam() then
		-- 本地清理队员ready
		self._team:clearAllReady()
	end

	-- 如果正在播放任务剧情，先暂时不显示战备界面
	if StoryManager:isEnterStoryMode() then
		self._teamReadyTargetId = targetId
		self._teamReadyIsMatch = isMatch
	else
		if not self:isMyTeam() then
			app:sendMsg("NewTeamReadyAndSettingController", "teamMemberStartVote", targetId, isMatch )
		end
		-- 停止任务追踪
		app:getLaunchCtl():endCharacterMove()
	end
end

-- 人物剧情播放完，显示战备确认界面
function ClassRef:showTeamReadyUIOnStoryOver()
	local targetId = self._teamReadyTargetId
	local isMatch = self._teamReadyIsMatch
	self._teamReadyTargetId = nil
	self._teamReadyIsMatch = nil

	if not targetId then return end
	if not self:hasTeam() then return end
	if not self:isMyTeam() then
		app:sendMsg("NewTeamReadyAndSettingController", "teamMemberStartVote", targetId, isMatch )
	end
end

-- 队员请求队长
function ClassRef:onImpeachCaptainRequest(ret)
	if self:_isCrossDungeon() then
		-- 跨服副本，直接拒绝
		self:reqImpeachLeaderResponses({ChangeUUID=ret.ChangeUUID, agree=false})
		return
	end

    app:sendMsg("NewTeamMemberController", "showTeamImpeachView", ret)
end


------------------------- 跨服匹配 start ---------------------
-- 跨服匹配结束清理
function ClassRef:_clearCrossMatchDatas()
	local datas = self._crossMatchDatas
    for i,data in ipairs(datas) do
        data.teamTarget:setIsInCrossMatch(false)
    end
    self._crossMatchDatas = {}
end

-- 跨服副本弹出消息提示
function ClassRef:_showCrossDungeonTips(tipStr)
	local tipParams = {remindId=Constant.FUNC_TYPE_CROSS_MATCH, params=tipStr}
	UIHandler:showThirdLevelTips(tipParams)
end

-- // 跨服匹配过程中的等待消息
-- message CrossDungeonMatchInfo {
--     int32 Target        = 1;
--     int64 AddStamp  = 2;
-- }
-- // 跨服匹配过程的提醒消息
-- message S2C_MatchNotify {
--     repeated CrossDungeonMatchInfo Infos = 1;
-- }
function ClassRef:S2C_MatchNotify(msg)
	-- dump(msg, "S2C_MatchNotify")

	local preDatas = self._crossMatchDatas
	self:_clearCrossMatchDatas()

    local datas = {}
    for i,v in ipairs(msg.Infos) do
        local data = {}
        data.targetId = v.Target
        data.teamTarget = self:getTeamTargetById(v.Target)
        data.startTime = v.AddStamp
        data.teamTarget:setIsInCrossMatch(true)
        datas[i] = data
    end
    self._crossMatchDatas = datas

    self:updateTeamCrossMatch()

    -- 弹出消息提示
    local reason = msg.reason
    local tipStr
    if reason == "LeaderCancel" then
    	-- 找出取消的玩法名字
    	local cancelName = ""
    	for i,v in ipairs(preDatas) do
    		local found = false
    		for i,data in ipairs(datas) do
    			if v.targetId == data.targetId then
    				found = true
    				break
    			end
    		end
    		if not found then
    			cancelName = v.teamTarget:getTaskTrackName()
    			break
    		end
    	end
    	tipStr = string.format(L("CrossServerTips10"), cancelName)
    elseif reason == "MemberQuit" then
    	tipStr = L("CrossServerTips11")
    elseif reason == "EnterTeam" then
    	tipStr = L("CrossServerTips12")
    elseif reason == "MemberAdd" then
    	tipStr = L("CrossServerTips13")
    elseif reason == "LeaveTeam" then
    	tipStr = L("CrossServerTips20")
    end
    if tipStr then
    	self:_showCrossDungeonTips(tipStr)
    end

    EM:notify("onTaskTrackChange")
    app:sendMsg("TeamMatchController", "refreshTeam")
    app:sendMsg("PvpChallengeController", "refreshTeam")
    app:sendMsg("TeamMatchController", "updateInCrossMatch")
    app:sendMsg("NewTeamReadyAndSettingController", "closeView")
end

-- 跨服副本匹配
function ClassRef:C2S_CrossDungeonMatch(targetId, cb)
	-- print("C2S_CrossDungeonMatch", targetId)
    app.session:request("pb_cross.C2S_CrossDungeonMatch", {Target=targetId}, function()
    	-- 清理自动申请目标
    	for i,id in ipairs(self._curAutoApplyTargetIds) do
    		local teamTarget = self._teamTargetDict[id]
    		teamTarget:setAutoApply(false)
    	end
    	self._curAutoApplyTargetIds = {}

    	local teamTarget = self:getTeamTargetById(targetId)
	    app:sendMsg("TeamMatchController", "updateAutoApply", teamTarget)
	    app:sendMsg("PvpEliteController", "updateAutoApply", teamTarget)
	    app:sendMsg("PvpChallengeController", "updateAutoApply", teamTarget)

    	executeFunc(cb)
    end)
end

-- 取消跨服副本匹配
function ClassRef:C2S_CancelCrossDungeonMatch(targetId)
	-- print("C2S_CancelCrossDungeonMatch", targetId)
    app.session:request("pb_cross.C2S_CancelCrossDungeonMatch", {Target=targetId})
end

-- //跨服匹配成功消息通知
-- message S2C_CrossDungeonMatchSuccessNotify {
--     int32 DungeonSubId                          = 1;    //副本ID
--     int32 MatchSuccessId                            = 2;    //用于标识匹配成功队列的ID
--     repeated CrossDungeonReadyInfo Infos    = 3;    //具体成员的准备消息
--     int64 ExpiredStamp                          = 4;    //匹配请求过期时间戳
-- }
function ClassRef:S2C_CrossDungeonMatchSuccessNotify(msg)
	-- dump(msg, "S2C_CrossDungeonMatchSuccessNotify", 10)
	self._teamMatchCrossInfo = TeamMatchCrossInfo.new(msg)
	self._teamMatchCrossInfo:setTeamTargetVo(self:getTeamTargetById(msg.DungeonSubId))

	app:sendMsg("TeamMatchCrossController", "openView")
end

-- 准备好进入跨服副本，对当前副本/战斗/UI做清理
function ClassRef:_clearForCrossMatch()
	-- print("BattleManager:isTraining()", BattleManager:isTraining(), BattleManager:isBattle())
	-- 清理战斗
	if BattleManager:isBattle() then
        BattleManager:goOutBattle(nil,nil,true)
    end

	-- 清理训练场
	if BattleManager:isTraining() then
		app.session:request("pb_training.C2S_Training_Leave", {})
	end

	-- 清理界面
	UIHandler:removeAllUI(true)
end

-- 跨服匹配成功后被中断
function ClassRef:S2C_CrossDungeonMatchReadyCancelNotify(msg)
	-- dump(msg, "S2C_CrossDungeonMatchReadyCancelNotify")
	app:sendMsg("TeamMatchCrossController", "closeView")

	local tipStr
	if msg.Reason == "SomeOneCancle" then
		tipStr = L("CrossServerTips14")
	elseif msg.Reason == "TimeOut" then
		tipStr = L("CrossServerTips15")
	elseif msg.Reason == "AllReady" then
		-- 准备好进入跨服副本，对当前副本/战斗做清理
		self:_clearForCrossMatch()
	end
	if tipStr then
		self:_showCrossDungeonTips(tipStr)
	end
end

-- 跨服匹配确认
function ClassRef:C2S_CrossDungeonMatchConfirm(isOK)
    local params = {MatchSuccessId=self._teamMatchCrossInfo.MatchSuccessId, State=isOK}
    -- dump(params, "C2S_CrossDungeonMatchConfirm params")
    app.session:request("pb_cross.C2S_CrossDungeonMatchConfirm", params, function(msg)
        -- dump(msg, "C2S_CrossDungeonMatchConfirm msg")

    end)
end
------------------------- 跨服匹配 end ----------------------

return ClassRef
